/*
 * 版权声明 (c) 2025 XXX科技有限公司
 *
 * 本软件及其相关文档文件受版权保护。未经版权所有者明确书面许可，任何单位或个人不得
 * 以任何形式复制、传播、修改、出售、出租、反向工程、反编译或利用本软件的任何部分。
 *
 * 对于任何违反本声明的行为，版权所有者保留追究法律责任的权利。
 */

#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <string>
#include <sstream>
#include <vector>
#include "inix.h"

using namespace std;

class Configure {
public:
	Configure(const Configure &)            = delete;
	Configure &operator=(const Configure &) = delete;
	Configure(Configure &&)                 = delete;
	Configure &operator=(Configure &&)      = delete;

	// 获取单例
	static Configure &Instance() {
		static Configure instance;
		return instance;
	}

	// 服务网关基础配置项
	struct {
		string   AppName          = "soeg_server"; // 应用名称
		uint16_t GatewayPort      = 5002;          // 网关端口(服务同步等通道)
		uint16_t StaticAgentPort  = 5003;          // 静态代理端口
		uint16_t DynamicAgentPort = 5004;          // 动态代理端口
	} Gateway;

	// 网关/组播配置
	struct {
		string   Addr     = "224.2.2.4"; // 组播监听地址
		uint16_t Port     = 1224;        // 组播端口
		uint16_t Interval = 5000;        // 间隔时间(毫秒)
	} Multicast;

	// 注册中心配置
	struct {
		string   Addr     = "127.0.0.1"; // 注册中心IP
		uint16_t Port     = 8500;        // 注册中心Port
		uint16_t Interval = 5000;        // 服务同步周期(毫秒)
	} Discovery;

	// 日志配置
	struct {
		string Level   = "info"; // 日志级别: debug|info|warn|error|fatal
		string Path    = "./";   // 日志文件路径(logs/dump.log)
		bool   Quiet   = false;  // 是否静默(true:关闭文件日志)
		int    AutoNum = 1;      // 日志文件编号

		int levelVal() {
			if (Level == "debug") return 0;
			if (Level == "info") return 1;
			if (Level == "warn") return 2;
			if (Level == "error") return 3;
			if (Level == "fatal") return 4;
			return 1;
		}
	} Logger;

	// 服务信息
	struct Service {
		string         Code;   // 服务标识
		string         Name;   // 服务名称
		string         Addr;   // 服务IP
		uint16_t       Port;   // 服务Port
		bool           Enable; // 是否启用
		static Service decode(const string &encoded) {
			Service       service;
			istringstream iss(encoded);
			getline(iss, service.Code, '|');
			getline(iss, service.Name, '|');
			getline(iss, service.Addr, '|');
			iss >> service.Port;
			iss.ignore(); // 忽略'|'
			iss >> service.Enable;
			return service;
		}
	};

	// 静态服务
	vector<Service> Services;

	int Load(const string &config_path) {
		dictionary *ini = ini_load(config_path.c_str());
		if (!ini) return -1; // 配置文件加载失败，使用默认配置项

		auto safe_getint = [&](const char *key, int def) { return ini_getint(ini, key, def); };
		auto safe_getstr = [&](const char *key, const char *def) {
			const char *v = ini_getstring(ini, key, def);
			return std::string(v ? v : def ? def : "");
		};

		// Gateway
		Gateway.AppName          = safe_getstr("Gateway:AppName", Gateway.AppName.c_str());
		Gateway.GatewayPort      = static_cast<uint16_t>(safe_getint("Gateway:GatewayPort", Gateway.GatewayPort));
		Gateway.StaticAgentPort  = static_cast<uint16_t>(safe_getint("Gateway:StaticAgentPort", Gateway.StaticAgentPort));
		Gateway.DynamicAgentPort = static_cast<uint16_t>(safe_getint("Gateway:DynamicAgentPort", Gateway.DynamicAgentPort));

		// Multicast
		Multicast.Addr     = safe_getstr("Multicast:Addr", Multicast.Addr.c_str());
		Multicast.Port     = static_cast<uint16_t>(safe_getint("Multicast:Port", Multicast.Port));
		Multicast.Interval = std::max(500, safe_getint("Multicast:Interval", Multicast.Interval));

		// Discovery
		Discovery.Addr     = safe_getstr("Discovery:Addr", Discovery.Addr.c_str());
		Discovery.Port     = static_cast<uint16_t>(safe_getint("Discovery:Port", Discovery.Port));
		Discovery.Interval = std::max(500, safe_getint("Discovery:Interval", Discovery.Interval));

		// Logger
		Logger.Level   = safe_getstr("Logger:Level", Logger.Level.c_str());
		Logger.Path    = safe_getstr("Logger:Path", Logger.Path.c_str());
		Logger.Quiet   = ini_getboolean(ini, "Logger:Quiet", Logger.Quiet ? 1 : 0) == 1;
		Logger.AutoNum = safe_getint("Logger:AutoNum", Logger.AutoNum);

		// Services
		Services.clear();
		for (int idx = 1;; ++idx) {
			char key[64];
			snprintf(key, sizeof(key), "Services:Service.%d", idx);
			std::string svcstr = safe_getstr(key, "");
			if (svcstr.empty()) break;
			try {
				Services.push_back(Service::decode(svcstr));
			} catch (...) {
				// 格式不合法，跳过
			}
		}

		ini_freedict(ini);
		return 0;
	}

private:
	Configure()  = default; // 私有构造函数
	~Configure() = default; // 私有析构函数
};
#endif // __CONFIG_H__

#if 0
int main() {
	auto &config = Configure::Instance();
	// config.Load("app.ini");
	config.Load("config_example.ini");

	cout << "Gateway:Name: " << config.Gateway.Name << endl;
	cout << "Gateway:GatewayPort: " << config.Gateway.GatewayPort << endl;
	cout << "Multicast:Addr: " << config.Multicast.Addr << endl;
	cout << "Multicast:Port: " << config.Multicast.Port << endl;
	cout << "Discovery:Port: " << config.Discovery.Port << endl;
	cout << "Logger:Path: " << config.Logger.Path << endl;
	cout << "Logger:Quiet: " << config.Logger.Quiet << endl << endl;

	for (auto svc: config.Services) {
		cout << "Service.Code: " << svc.Code << endl;
		cout << "Service.Name: " << svc.Name << endl;
		cout << "Service.Addr: " << svc.Addr << endl;
		cout << "Service.Port: " << svc.Port << endl;
		cout << "Service.Enable: " << svc.Enable << endl << endl;
	}
	return 0;
}
#endif
